package com.piece.core.authentication.exception;

import com.piece.core.framework.constant.ExceptionAuthConstants;
import com.piece.core.framework.enums.HeaderType;
import com.piece.core.framework.support.response.AjaxResponse;
import com.piece.core.framework.util.basic.I18nUtil;
import org.apache.commons.httpclient.HttpStatus;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.ProviderNotFoundException;
import org.springframework.security.oauth2.common.DefaultThrowableAnalyzer;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.security.oauth2.common.exceptions.UnsupportedGrantTypeException;
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
import org.springframework.security.web.util.ThrowableAnalyzer;

public class CustomWebResponseExceptionTranslator implements WebResponseExceptionTranslator {

    private ThrowableAnalyzer throwableAnalyzer = new DefaultThrowableAnalyzer();

    public CustomWebResponseExceptionTranslator() {
    }

    @Override
    public ResponseEntity translate(Exception e) {
        Throwable[] causeChain = this.throwableAnalyzer.determineCauseChain(e);
        Exception ase = (OAuth2Exception) this.throwableAnalyzer.getFirstThrowableOfType(OAuth2Exception.class, causeChain);
        if (null != ase) {
            if (ase.getCause() instanceof UnsupportedGrantTypeException) {
                return this.handleOAuth2Exception(HttpStatus.SC_BAD_REQUEST, I18nUtil.message(ExceptionAuthConstants.GRANT_INVALID));
            }
            return this.handleOAuth2Exception(HttpStatus.SC_INTERNAL_SERVER_ERROR, ase.getMessage());
        } else if (e instanceof ProviderNotFoundException) {
            return this.handleOAuth2Exception(HttpStatus.SC_INTERNAL_SERVER_ERROR, I18nUtil.message(ExceptionAuthConstants.GRANT_INVALID));
        } else {
            return this.handleOAuth2Exception(HttpStatus.SC_UNAUTHORIZED, e.getMessage());
        }
    }

    private ResponseEntity handleOAuth2Exception(int code, String message) {
        HttpHeaders headers = new HttpHeaders();
        headers.set(HeaderType.CACHE_CONTROL.getValue(), "no-store");
        headers.set(HeaderType.PRAGMA.getValue(), "no-cache");
        ResponseEntity<AjaxResponse> response = new ResponseEntity(AjaxResponse.error(code, message), headers, HttpStatus.SC_OK);
        return response;
    }
}
